/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controller;

import GUI.JFrameBase;
import dcm4che.JPG2dcm;
import dcm4che.dcmMWL;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import libraries.Application;
import libraries.FileLibrary;
import libraries.FunctionLibrary;
import libraries.LanguageLibrary;
import model.Consultation;
import model.DB2Hash;
import org.dcm4che2.data.DicomElement;
import org.dcm4che2.data.DicomObject;
import view.AcquisitionPanelView;
import view.PatientPanelView;
import view.Server;
import view.Physician;
import view.StudyPanelView;
import view.WorklistPanelView;

/**
 *
 * @author aeguzkiza
 */
public class Controller {
    public static class MyException extends Exception {        
        static final int DBUpdateSuccess = 1;   // Don't change: DBUpdateSuccess = 1 this one defines also info logo.
        static final int DBUpdateError = 2;     // Don't change: DBUpdateError = 2 this one defines also error logo.   
        private int type;
        private String string;

        public MyException(int type, String string) {
            super();
            this.type = type;
            this.string = string;
        }
        public int getType(){
            return type;
        }
        
        public String getTitle() {
            switch (type) {                
                case DBUpdateSuccess:
                    return "INFORMACIÓN: La base de datos ha sido actualizada";    
                case DBUpdateError:
                    return "ERROR: La base de datos no se ha podido actualizar";    
                default:
                    return "ERROR DESCONOCIDO";
            }
        }
        
        @Override
        public String getMessage() {
            return string;            
        }
                
        
    }
    
    private String patientAdded = "Paciente añadido correctamente";
    private String studyAdded = "Estudio añadido correctamente";
    private String acquisitionAdded = "Adquisición añadida correctamente";
    private String worklist_error = "Error al intentar establecer asociación con el servidor de Worklist:\n";

    private FileLibrary FLib = new FileLibrary();
    private FunctionLibrary FL = new FunctionLibrary();
    private LanguageLibrary LL = new LanguageLibrary();
    Consultation consultation;
    JPG2dcm jpg2dcm;
    final int ORDER_BY_NAME = 0;
    final int ORDER_BY_NAME_AND_STUDY = 1;
    final int ORDER_BY_NAME_AND_WORKLIST = 2;
    final int ORDER_BY_STUDY = 3;
    final int ORDER_BY_PHYSICIAN = 4;
    final int ORDER_BY_AET = 5;
    final int ORDER_BY_ID = 6;

    int selectedPatientId = 0;    
    int selectedStudyId = 0;
    int selectedPhysicianId = 0;
    
    DB2Hash patient2db = new DB2Hash(); 
    DB2Hash worklist2db = new DB2Hash();
    DB2Hash study2db = new DB2Hash();
    DB2Hash acquisition2db = new DB2Hash();
    
    
    public static DicomObject getObjectItem(DicomObject object,int Tag){

        DicomElement cmtSequence = object.get(Tag);
        DicomObject dcm = null;

        if (cmtSequence.hasDicomObjects() ){
            for(int i=1;i<cmtSequence.countItems();i++)
                dcm = cmtSequence.getDicomObject(i);
                return dcm;
        }else{
            return object;
        }
    }
    
    public void updateWorklist(JFrameBase frame){
        WorklistPanelView worklistView = new WorklistPanelView(frame);  // Creates a studyPanelView instance inside JFrameBase.
        try {
            Server server = (Server) frame.selectedServerComboBox1.getSelectedItem();   // Get Server atributes from JSelectBox.
            DB2Hash device = this.consultation.getAttributes("device"); // Get Device attributes from the first row of the table device in DB.            
            ArrayList<String> filters = worklistView.getWorklistFilters();
            dcmMWL MWL = new dcmMWL(frame,device,server.getServer(),filters);
            
            List<DicomObject> worklist = MWL.getWorklist();
            
            // First of all, delete all data from the table.                        
            consultation.delete("dicom_obj");     
            
            ArrayList<String> keysObj = consultation.getKeys("dicom_obj");
            ArrayList<String> keysAttr = consultation.getKeys("dicom_attr");
            System.out.println("keysObj: "+keysObj);
            System.out.println("keysAttr: "+keysAttr);
                        
            // SAVING WORKLIST IN DATABASE:    
            for(int i=0;i<worklist.size();i++){   
            // DICOM object level:    
                ArrayList<ArrayList<String>> attributes = MWL.Dicom2Array(worklist.get(i));
                System.out.println("Attributes: "+attributes);
                String currentProcedureStepID = MWL.getScheduledProcedureStepID();
                System.out.println("CurrentProcedureStepID: "+currentProcedureStepID);
                
                // Create new DICOM object.
                DB2Hash dicomObject = new DB2Hash();
                dicomObject.set(keysObj.get(0), null);
                dicomObject.put(keysObj.get(1), currentProcedureStepID);
                dicomObject.put(keysObj.get(2), "mwl");
                
                  
                
                Integer objId = consultation.add(dicomObject, "dicom_obj", true);
                if(objId == null){
                    objId = consultation.getId("dicom_obj", keysObj.get(1), currentProcedureStepID);
                    String error = "El objeto DICOM ya había sido incluído en la base de datos.\n Revise posible dupliciadad para los atributos DICOM.";
                    throw new MyException(MyException.DBUpdateError, error);
                }

                System.out.println("DICOM object written. "+objId);
                // Froga
                DB2Hash worklistAttribute = new DB2Hash();
                worklistAttribute.put(keysAttr.get(0), Integer.toString(objId));                                    

                System.out.println("Attributes size: "+attributes.size());
                // Attribute level:
                for(int j=0;j<attributes.get(0).size();j++){   
                    // Column level:                    
                    for(int k=0;k<keysAttr.size()-1;k++){ 
                        //ArrayList<String> attributes2Hash = attributes.get(j));
                        String attributes2Hash = attributes.get(k).get(j);                           
                        worklistAttribute.put(keysAttr.get(k+1), attributes2Hash);         // Start from Tag column.         
                        //System.out.println("Keys: "+keysAttr.get(k+1)+">> Attributes2Hash: "+attributes2Hash);
                    }
                    System.out.println("worklistAttribute: "+worklistAttribute);

                    // Froga
                    consultation.add(worklistAttribute, "dicom_attr", false);   // Key variables there are generated by referencing the dicom_obj table.
                
                }                
            }
            
            
            // WORKLIST FROM DATABASE TO JTABLE:   
            // 1.- Delete previous worklist from JTable.
            for (int j = 0; j < controllerAddListener.size(); j++) { 
                controllerAddListener.get(j).deleteReferralnotes();
            }
            
            // 2.- Write new worklist on JTable.
            List<String> var = new ArrayList<String>();
            var.add("type");    // Dicom objects must be worklist type.
            
            ArrayList<Integer> dicomObjects = consultation.getList("dicom_obj", var, "mwl", ORDER_BY_ID);   // Get worklist dicom objects on database.            
            System.out.println("DicomObjects: "+dicomObjects.size());            
            /* // If there are dicomObjects but they were added to the worklist, this code wouldn't work. 
            if(dicomObjects.isEmpty()){ 
                String error = "Los parámetros de búsqueda no han devuelto ningún resultado."; 
                throw new MyException(MyException.DBUpdateError, error); 
            }*/
            
            ArrayList<String> referralInWorklist = consultation.getAttributeList("worklist","ScheduledProcedureStepID",ORDER_BY_ID);
            System.out.println("referralInWorklist: "+referralInWorklist);
            
            ArrayList<DB2Hash> referralNote = new ArrayList<DB2Hash>();
            for(int i=0;i<dicomObjects.size();i++){                
                String referralName = consultation.getAttributes("dicom_obj", dicomObjects.get(i)).get("name");
                int duplicatedReferral = referralInWorklist.indexOf(referralName);
                
                if(duplicatedReferral < 0){ // If there's not coincidence worklist-database: We can show this referral note in worklist table.                             
                    //! Load an array of DB2Hashes. Not only the first one.
                    referralNote = consultation.getAttributes_Id("dicom_attr", "dicom", dicomObjects.get(i));
                    System.out.println("ReferralNote: "+referralNote);

                    for (int j = 0; j < controllerAddListener.size(); j++) {                    
                        controllerAddListener.get(j).updateAddReferralnote(referralNote);
                    }
                }
            }   
            // Alert if the table get's empty.
            if(frame.WorklistXTable.getRowCount() == 0){ 
                String error = "Los parámetros de búsqueda no han devuelto ningún resultado."; 
                throw new MyException(MyException.DBUpdateError, error); 
            }
            
        } catch (MyException ex) {  // Detects if the PACS isn't available.
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.Worklist, error_txt, ex.getTitle(), ex.getType(), null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {  // Detects if the PACS isn't available.
            String error_txt = this.worklist_error+Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.Worklist, error_txt, frame.EXCEPTION, 2, null);
        } catch (InterruptedException ex) {
            String error_txt = this.worklist_error+Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.Worklist, error_txt, frame.EXCEPTION, 2, null);
        } catch (dcmMWL.MyException ex) {
            String error = ex.getMessage();
            JOptionPane.showMessageDialog(frame.Worklist, error, frame.EXCEPTION, 2, null);            
        } catch (SQLException ex) {
            String error_txt = this.worklist_error+Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.Worklist, error_txt, frame.EXCEPTION, 2, null);  
        } catch (Exception ex) {        
            String error_txt = this.worklist_error+Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.Worklist, error_txt, frame.EXCEPTION, 2, null); 
        }  
    }
    
    public void readReferralNote(JFrameBase frame){
        // 1.- Get data from WorklistPanelView.         
        WorklistPanelView worklistPanelView = new WorklistPanelView(frame);                
        DB2Hash referralNote = worklistPanelView.getReferralNote();
        System.out.println("Selected referralNote: "+referralNote);
        
            
        // 2.- Translate DICOM attributes into usable data.
        ArrayList<DB2Hash> referral2db = LL.processReferral(referralNote);   // Process a referral note to convert it into database format.
        this.patient2db = referral2db.get(0);
        System.out.println("Patient data from referralNote: "+patient2db);
        this.worklist2db = referral2db.get(1);
        System.out.println("Worklist data from referralNote: "+worklist2db);
        this.study2db = referral2db.get(2);
        System.out.println("Study data from referralNote: "+study2db);
        this.acquisition2db = referral2db.get(3);
        System.out.println("Acquisition data from referralNote: "+acquisition2db);
                                    
        // 3.- Put usable data into ReferralNote panel.
        for (int i = 0; i < controllerAddListener.size(); i++) { 
            controllerAddListener.get(i).previewReferralnote(worklist2db,study2db,patient2db);
        }
    }
        
    public void ReferralNote2database(JFrameBase frame){
        Integer worklistId = null;
        Integer studyId = null;
        Integer acquisitionId = null;
        Integer physicianId = null;
        Integer patientId = null;
        String deviceId = null;
        
        try {
            System.out.println("<<< START OF ReferralNote2database >>>");
            
            // 4.- Put new study into DB.
            DB2Hash device = this.consultation.getAttributes("device"); // Get Device attributes from the first row of the table device in DB.            
            deviceId = device.get("Id");   
            System.out.println("DeviceId: "+deviceId);
        
        } catch (Exception ex) {
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ReferralNote, error_txt, frame.MYSQL_EXCEPTION, 2, null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }  
        
        try {
            
            Physician physician = (Physician) frame.PerformingPhysicianNameComboBox.getSelectedItem();  // Get currently selected physician.
            physicianId = physician.getPhysicianId();
            System.out.println("PhysicianId: "+physicianId);
            
            // Write new worklist & study to database.
            worklistId = consultation.add(this.worklist2db, "worklist", true);
            studyId = consultation.add(this.study2db, "study", true);
            if(worklistId == null){
                worklistId = consultation.getId("worklist", "AccessionNumber", this.worklist2db.get("AccessionNumber"));
                String error = "El volante electrónico ya había sido incluído en la base de datos.\n Revise posible dupliciadad para los atributos 'accession number' y 'requested procedure id'.";
                throw new MyException(MyException.DBUpdateError, error);
            }else if(studyId == null){
                studyId = consultation.getId("study", "StudyId", this.study2db.get("StudyId"));
                consultation.delete(worklistId, "worklist");    // Delete last written referral note.
                String error = "El estudio ya había sido incluído en la base de datos.\n Revise posible dupliciadad para los identificadores de estudio 'StudyId' o 'StudyInstanceUID'.";
                throw new MyException(MyException.DBUpdateError, error);
            }
            
            // Write new patient to database.
            patientId = consultation.add(this.patient2db, "patient", true);
            if(patientId == null){
                patientId = consultation.getId("patient", "PatientID", this.patient2db.get("PatientID"));
                System.out.println("Updating patient: "+patientId);
            }   
            
            // Write new acquisitions in database.
            // Editando... >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            this.acquisition2db.set("study_Id", studyId.toString()); // Add study_Id data to acquisition table.           
            String ImageLaterality = this.acquisition2db.get("ImageLaterality");
            if(ImageLaterality == null){
                ImageLaterality = "B";    // !!! For test purposes: both eyes by default.
            }
            if(ImageLaterality != null){
                String laterality = FL.eyeTranslation(ImageLaterality);
                
                if(laterality.equals("OI") || laterality.equals("OD")){ // Left or right eye.
                    acquisition2db.set("ImageLaterality", ImageLaterality);
                    acquisition2db.set("AcquisitionTime", this.worklist2db.get("ScheduledProcedureStepTime"));  // Predicted acquisition time.
                    acquisitionId = consultation.add(acquisition2db, "acquisition", true);
                            
                    if(acquisitionId == null){  // Not necessary???
                        acquisitionId = consultation.getId("acquisition", "AcquisitionName", acquisition2db.get("AcquisitionName"));
                        System.out.println("Updating acquisition: "+acquisitionId);
                        String error = "Esta adquisición ya había sido incluída en la base de datos.\n Revise posible dupliciadad en el identificador de adquisición 'AcquisitionName'\no en la imágen cargada 'ImagePath'.";
                        throw new MyException(MyException.DBUpdateError, error);
                    }
                    
                }else if(laterality.equals("OI+OD")){ // Both eyes.
                    // Left eye:
                    acquisition2db.set("ImageLaterality", "L");
                    acquisition2db.set("AcquisitionTime", this.worklist2db.get("ScheduledProcedureStepTime"));  // Predicted acquisition time.
                    acquisitionId = consultation.add(acquisition2db, "acquisition", true);
                    
                    if(acquisitionId == null){
                        acquisitionId = consultation.getId("acquisition", "AcquisitionName", acquisition2db.get("AcquisitionName"));
                        System.out.println("Updating acquisition: "+acquisitionId);
                        String error = "Esta adquisición ya había sido incluída en la base de datos.\n Revise posible dupliciadad en el identificador de adquisición 'AcquisitionName'\no en la imágen cargada 'ImagePath'.";
                        throw new MyException(MyException.DBUpdateError, error);
                    }
                    
                    // Right eye:
                    acquisition2db.set("ImageLaterality", "R");
                    acquisitionId = consultation.add(acquisition2db, "acquisition", true);
                    
                    if(acquisitionId == null){
                        acquisitionId = consultation.getId("acquisition", "AcquisitionName", acquisition2db.get("AcquisitionName"));
                        System.out.println("Updating acquisition: "+acquisitionId);
                        String error = "Esta adquisición ya había sido incluída en la base de datos.\n Revise posible dupliciadad en el identificador de adquisición 'AcquisitionName'\no en la imágen cargada 'ImagePath'.";
                        throw new MyException(MyException.DBUpdateError, error);
                    }
                }
                
            }
            // Editando... >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            
            // Write new Consultation in database.
            ArrayList<String> consultationKeys = consultation.getKeys("consultation");

            // Adding attribute values to DB2Hash.
            DB2Hash consultationHash = new DB2Hash();
            List<String> values = Arrays.asList(worklistId.toString(),studyId.toString(),physicianId.toString(),patientId.toString(),deviceId);   // Worklist Hashtable: Not obligatory, so if it doesn't exist set to null.

            for(int j = 0; j<consultationKeys.size();j++){  // Doesn't write Id value.
                System.out.println("Keys: "+consultationKeys.get(j)+" Values: "+values.get(j));
                consultationHash.put(consultationKeys.get(j), values.get(j));
            }

            // Writting table consultation on database.
            consultation.add(consultationHash, "consultation",false);
            
            // Close referral note panel.            
            frame.ReferralNote.setVisible(false);
            
            // Check keys in dicom2db table.
            /*for(int i=0;i<referralNote.size();i++){
                Integer isDefined = consultation.getId("worklist","DatabaseName",keys.get(i));

                System.out.println("isDefined: "+isDefined);
                if(isDefined.toString().isEmpty()){
                    // Fill this attribute in database.
                    consultation.
                }
            }*/
                
                
                    /*        
                    // Option A:
                    Integer isDefined = consultation.getId("worklist","Tag",Tag);   // Is this attribute defined on dicom2db table?
                    if(isDefined.toString().isEmpty()){
                       // Fill this attribute in database. Gets the attributeName value from jList and insert it to database.
                        
                    }
                    
                    // Option B:
                    boolean isThere = referralNote.containsKey(Tag);
                    if(isThere){ // There's coincidence between the two ArrayLists.    
                        String Element = referralNote.get(Tag);
                        worklist2DB.set(keys.get(j), Element);                    
                    }
                    
                    /*String index = referralNote.get();
                    System.out.println("Worklist keys: "+keys+" Index: "+index);
                    
                    int index = TagsDB.indexOf(referralNote.get("dicom_Id"));
                    System.out.println("Worklist attributes: "+referralNote.get(index)+" TagsDB: "+TagsDB+" Index: "+index);
                    if(index >= 0){ // There's coincidence between the two ArrayLists.                                                
                        worklist2DB.set(keys.get(index), referralNote.get("").get(j));
                        System.out.println("Worklist attribute name: "+keys.get(index)+" value: "+attributes.get(2).get(j));
                    }*/
            
            
                    
            
            // 5.- Put new study into JTree.
            // Initialize Treemodels:
            frame.topPatient.removeAllChildren();
            frame.topWorklist.removeAllChildren();
            // Put new data in Treemodels:
            List<String> list = null;
            this.loadPatientList(list,null);       // Initializes each Jtree. Doesn't need controller.
            frame.modelPatient.reload();
            frame.model.reload();
                
            String error = "El volante ha sido incluído con éxito en la base de datos.\n Los datos relativos al mismo se han añadido a la lista de trabajo.";
            throw new MyException(MyException.DBUpdateSuccess, error);            
            
        } catch (MyException ex) {
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ReferralNote, error_txt, ex.getTitle(), ex.getType(), null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ReferralNote, error_txt, frame.MYSQL_EXCEPTION, 2, null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }         
    }
    
    
    public void readWorklist(){

    /*
            // Write worklist in database:
            DB2Hash mwl2DB = new DB2Hash();
            ArrayList<String> keys = consultation.getKeys("dcmmwl");  // DICOM Worklist DB keys.
            
            Integer dcmmwlId = consultation.getId("dcmmwl","ScheduledProcedureStepID",mwl2DB.get("ScheduledProcedureStepID"));   // Already exists this row in DICOM Worklist DB?;
            
            for(int j=0;j<worklist.size();j++){
                int index = TagsDB.indexOf(worklistTags.get(j));
                //System.out.println("Worklist attributes: "+worklistTags.get(j)+" TagsDB: "+TagsDB+" Index: "+index);
                if(index >= 0){ // There's coincidence between the two ArrayLists.
                    mwl2DB.set(keys.get(index), attributes.get(2).get(j));
                    System.out.println("Study attribute name: "+keys.get(index)+" value: "+attributes.get(2).get(j));
                }
            }
            dcmmwlId = consultation.add(mwl2DB,"dcmmwl", true);
            
            
            //************************************************************/
            
            worklistView.clearWorklistTable();  // Initialize Worklist table.
            
            // Extract data from Worklist.
            for(int i=0;i<worklist.size();i++){
                
                ArrayList<ArrayList<String>> attributes = MWL.Dicom2Array(worklist.get(i)); // [Tag,VR,Value].   
                String scheduledProcedureStepID = MWL.getScheduledProcedureStepID();    // Identifies the referral note into the PACS.
                System.out.println("Worklist identifier: "+scheduledProcedureStepID);  
                System.out.println("Attribute List: "+attributes);  // All data from referral notes.
                ArrayList<String> worklistTags = attributes.get(0); // Get tags from worklist's attributes.  
                
                
                                               
                // READING FROM WORKLIST:
                // Get worklist attributes from database.
                DB2Hash worklist2DB = new DB2Hash();
                ArrayList<String> keys = consultation.getKeys("worklist");  // Worklist DB keys.
                ArrayList<String> TagsDB = LL.getWorklistAttributeTags(keys);   // Worklist keys to tag list.                
                
                for(int j=0;j<worklistTags.size();j++){
                    int index = TagsDB.indexOf(worklistTags.get(j));
                    //System.out.println("Worklist attributes: "+worklistTags.get(j)+" TagsDB: "+TagsDB+" Index: "+index);
                    if(index >= 0){ // There's coincidence between the two ArrayLists.                                                
                        worklist2DB.set(keys.get(index), attributes.get(2).get(j));
                        System.out.println("Worklist attribute name: "+keys.get(index)+" value: "+attributes.get(2).get(j));
                    }
                }

                // Get study attributes from worklist.
                DB2Hash study2DB = new DB2Hash();
                keys = consultation.getKeys("study");  // Worklist DB keys.
                TagsDB = LL.getStudyAttributeTags(keys);   // Study keys to tag list.

                for(int j=0;j<worklistTags.size();j++){
                    int index = TagsDB.indexOf(worklistTags.get(j));
                    //System.out.println("Worklist attributes: "+worklistTags.get(j)+" TagsDB: "+TagsDB+" Index: "+index);
                    if(index >= 0){ // There's coincidence between the two ArrayLists.
                        study2DB.set(keys.get(index), attributes.get(2).get(j));
                        System.out.println("Study attribute name: "+keys.get(index)+" value: "+attributes.get(2).get(j));
                    }
                }
                
                // Get Patient's attributes from database.
                DB2Hash patient2DB = new DB2Hash();
                keys = consultation.getKeys("patient");    // Patient DB keys.
                TagsDB = LL.getPatientAttributeTags(keys);   // Worklist keys to tag list.

                for(int j=0;j<worklistTags.size();j++){
                    int index = TagsDB.indexOf(worklistTags.get(j));
                    //System.out.println("Worklist attributes: "+worklistTags.get(j)+" TagsDB: "+TagsDB+" Index: "+index);
                    if(index >= 0){ // There's coincidence between the two ArrayLists.
                        if(keys.get(index).equals("PatientsName")){
                            ArrayList<String> DICOMname = FL.getName(attributes.get(2).get(j),"^");
                            patient2DB.set("PatientsName", DICOMname.get(0));
                            patient2DB.set("PatientsSurName", DICOMname.get(1));
                        }else{
                            patient2DB.set(keys.get(index), attributes.get(2).get(j));
                        }
                        System.out.println("Patient attribute name: "+keys.get(index)+" value: "+attributes.get(2).get(j));
                    }
                }

                // Get Physician's attributes from database.
                DB2Hash physician2DB = new DB2Hash();
                keys = consultation.getKeys("physician");    // Physician DB keys.
                TagsDB = LL.getPhysicianAttributeTags(keys);   // Worklist keys to tag list.

                for(int j=0;j<worklistTags.size();j++){
                    int index = TagsDB.indexOf(worklistTags.get(j));
                    //System.out.println("Worklist attributes: "+worklistTags.get(j)+" TagsDB: "+TagsDB+" Index: "+index);
                    if(index >= 0){ // There's coincidence between the two ArrayLists.
                        if(keys.get(index).equals("PerformingPhysiciansName")){
                            ArrayList<String> DICOMname = FL.getName(attributes.get(2).get(j),"^");
                            physician2DB.set("PerformingPhysiciansName", DICOMname.get(0));
                            physician2DB.set("PerformingPhysiciansSurName", DICOMname.get(1));
                        }else{
                            physician2DB.set(keys.get(index), attributes.get(2).get(j));
                        }
                        System.out.println("Patient attribute name: "+keys.get(index)+" value: "+attributes.get(2).get(j));
                    }
                }

                // Get Id from the current device in use.
                Integer deviceId = Integer.parseInt(device.get("Id"));  // Get deviceId that will be used later.
                
                // Writing new Worklist into the table:  
                ArrayList referralNote = new ArrayList();                
                //referralNote.add(worklist2DB.get("ScheduledProcedureStepStartDate"));
                //referralNote.add(worklist2DB.get("RequestedProcedurePriority"));
                referralNote.add(worklist2DB.get("ScheduledProcedureStepDateTime"));
                referralNote.add("RequestedProcedurePriority");
                referralNote.add(patient2DB.get("PatientID"));
                referralNote.add(patient2DB.get("PatientsName")+patient2DB.get("PatientsSurName"));
                referralNote.add(patient2DB.get("PatientsSex"));
                referralNote.add(patient2DB.get("PatientsBirthDate"));
                referralNote.add(worklist2DB.get("AccessionNumber"));
                referralNote.add(worklist2DB.get("ScheduledProcedStepDescription"));
                referralNote.add(worklist2DB.get("RequestedProcedureDescription"));
                referralNote.add(worklist2DB.get("RequestingPhysician"));
                worklistView.setReferralNote(referralNote);
                
                
                // WRITING INTO THE DATABASE:
                // Write a new Worklist in database.
                Integer worklistId = consultation.getId("worklist","AccessionNumber",worklist2DB.get("AccessionNumber"));   // Already exists this row in worklist DB?
                Integer studyId;
                if(worklistId == null){ // The current accession number there's not already stored in database.
                    worklist2DB.set("Id", null);
                    worklistId = consultation.add(worklist2DB, "worklist", true);    // Overwrite worklistId attribute.
                    worklist2DB.set("Id", worklistId.toString());  // Add the new worklistId after writting it in the database.
                                        
                    
                    study2DB.set("Id",null);
                    studyId = consultation.add(study2DB, "study", true);    // Overwrite studyId attribute.
                    study2DB.set("Id", studyId.toString());                 // Add the new studyId after writting it in the database.
                }else{
                    worklist2DB.set("Id", worklistId.toString());
                    consultation.update(worklist2DB, "worklist");    // New patientId after writting it in the database.

                    DB2Hash studyInConsultation = consultation.getAttributes_Id("consultation","worklist",worklistId).get(0);    // Get the first result from array.
                    studyId = Integer.parseInt(studyInConsultation.get("study_Id"));    // Get studyId from consultation.
                }                
                System.out.println("WorklistId: "+worklistId);
                
                
                // Write a new Patient in Database.
                // Patients name trick.
                Integer patientId = consultation.getId("patient","PatientID",patient2DB.get("PatientID"));   // Already exists this row in patient DB?
                if(patientId == null){ // The current accession number there's not already stored in database.
                    patient2DB.set("Id", null);
                    patientId = consultation.add(patient2DB, "patient", true);    // Overwrite patientId attribute.
                    patient2DB.set("Id", patientId.toString());  // Add the new patientId after writting it in the database.
                }/*else{    // The worklist creates a new Patient, but never changes an existing one!
                    patient2DB.set("Id", patientId.toString());
                    consultation.update(patient2DB, "patient");    // New patientId after writting it in the database.
                }*/
                System.out.println("PatientId: "+patientId);

                // Physicians name trick.
                Integer physicianId = consultation.getId("physician","PhysicianId",physician2DB.get("PhysicianId"));   // Already exists this row in patient DB?
                if(physicianId == null){ // The current accession number there's not already stored in database.
                    physician2DB.set("Id", null);
                    physicianId = consultation.add(physician2DB, "physician", true);    // Overwrite physicianId attribute.
                    physician2DB.set("Id", physicianId.toString());  // Add the new physicianId after writting it in the database.
                }/*else{    // The worklist creates a new Physician, but never changes an existing one!
                    physician2DB.set("Id", physicianId.toString());
                    consultation.update(physician2DB, "physician");    // New physicianId after writting it in the database.
                }*/
                System.out.println("PhysicianId: "+physicianId);
               
                
                // Write new Study in database.

                // Write new Consultation in database.
                ArrayList<String> consultationKeys = consultation.getKeys("consultation");
                DB2Hash consultationHash = new DB2Hash();

                List<String> values = Arrays.asList(worklistId.toString(),studyId.toString(),physicianId.toString(),patientId.toString(),deviceId.toString());   // Worklist Hashtable: Not obligatory, so if it doesn't exist set to null.
                //consultationHash.set("worklist", null);
                for(int j = 0; j<consultationKeys.size();j++){  // Doesn't write Id value.
                    System.out.println("Keys: "+consultationKeys.get(j)+" Values: "+values.get(j));
                    consultationHash.put(consultationKeys.get(j), values.get(j));
                }
                // Writting new tables on database.
                consultation.add(consultationHash, "consultation",false);



                //DicomObject objectSQ = getObjectItem(object,Tag.PixelMeasuresSequence );
                //System.out.println("MODALITY:"+objectSQ.getString(Tag.Modality));

                /*//System.out.println("PatientName: "+worklist.get(i).dataset());
                System.out.println("PatientName: "+worklist.get(i).getString(Tag.PatientName, VR.PN));
                System.out.println("PatientID: "+worklist.get(i).getString(Tag.PatientID, VR.LO));
                System.out.println("PatientBirthDate: "+worklist.get(i).getString(Tag.PatientBirthDate, VR.DA));
                System.out.println("PatientSex: "+worklist.get(i).getString(Tag.PatientSex, VR.CS));
                System.out.println("PatientComments: "+worklist.get(i).getString(Tag.PatientComments, VR.LT));

                System.out.println("ScheduledProcedureStepSequence: "+worklist.get(i).getString(Tag.ScheduledProcedureStepSequence, VR.SQ));
                System.out.println("Modality: "+worklist.get(i).getString(Tag.Modality, VR.CS));
                System.out.println("PerformedStationAETitle: "+worklist.get(i).getString(Tag.PerformedStationAETitle, VR.AE));

                System.out.println("AccessionNumber: "+worklist.get(i).getString(Tag.AccessionNumber, VR.SH));
                System.out.println("ReferringPhysicianName: "+worklist.get(i).getString(Tag.ReferringPhysicianName, VR.PN));
                System.out.println("RequestingPhysician: "+worklist.get(i).getString(Tag.RequestingPhysician, VR.PN));
                System.out.println("ScheduledProcedureStepStartDateTime: "+worklist.get(i).getString(Tag.ScheduledProcedureStepStartDateTime, VR.DT));
                System.out.println("ScheduledProcedureStepStartDate: "+worklist.get(i).getString(Tag.ScheduledProcedureStepStartDate, VR.DA));
                System.out.println("ScheduledProcedureStepStartTime: "+worklist.get(i).getString(Tag.ScheduledProcedureStepStartTime, VR.TM));
                System.out.println("ScheduledProcedureStepID: "+worklist.get(i).getString(Tag.ScheduledProcedureStepID, VR.SH));*/

            }
    }
    
    public void addNewPatient(JFrameBase frame) {
        PatientPanelView patientPanelView = new PatientPanelView(frame);
        DB2Hash patient = patientPanelView.getPatientData();
        DB2Hash oldPatient = null;
        try{
            if(!patient.isEmpty()){
                boolean isNew = patientPanelView.isNew;
                System.out.println("isNew: "+isNew);
                if(isNew){  // Create a new patient
                    patient.set("Id", null);
                    Integer id = consultation.add(patient,"patient",true);    // New patientId after writting it in the database.
                    
                    if(id == null){
                        id = consultation.getId("patient", "PatientID", patient.get("PatientID"));
                        System.out.println("Updating patient: "+id);
                        String error = "Este paciente ya había sido incluído en la base de datos.\n Revise posible dupliciadad en los datos de paciente.";
                        throw new MyException(MyException.DBUpdateError, error);
                    }                    
                    patient.set("Id", id.toString());  // Add the new patientId after writting it in the database.
                    
                }else{  // Update an old patient.
                    System.out.println("HCE: "+patient.get("PatientID"));
                    Integer patientId = consultation.getId("patient","PatientID",patient.get("PatientID"));
                    oldPatient = consultation.getAttributes("patient", patientId);
                    patient.set("Id", patientId.toString());
                    consultation.update(patient,"patient");
                }
                //JOptionPane.showMessageDialog(frame.DemographicPanel, patientAdded, frame.infoTxt,JOptionPane.INFORMATION_MESSAGE);

                for (int i = 0; i < controllerAddListener.size(); i++) {
                    controllerAddListener.get(i).updateEditPatient(isNew,oldPatient,patient);
                }
            }
        }catch(MyException ex){//JOptionPane.ERROR_MESSAGE
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.DemographicPanel, error_txt, ex.getTitle(), ex.getType(), null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }catch(SQLException ex){//JOptionPane.ERROR_MESSAGE
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.DemographicPanel, error_txt, frame.MYSQL_EXCEPTION, 2, null);
        }catch(Exception ex){
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.DemographicPanel, error_txt, frame.EXCEPTION, 2, null);
        }
    }
    public void checkPatientHCE(String HCE) {   // Checks Patient HCE when is writed in it's textfield.
        try {
            // Checks Patient HCE when is writed in it's textfield.
            int HCE_exists = 1;
            Integer patientId = consultation.getId("patient","PatientID",HCE);
            System.out.println("patientId: " + patientId);
            if (HCE.equals("")) {
                HCE_exists = 2;
            } else if (patientId != null) {
                changeSelectedPatient(patientId); // Load patient if exists a coincidence.
                HCE_exists = 0;
            }
            for (int i = 0; i < controllerAddListener.size(); i++) {
                controllerAddListener.get(i).checkAddHCE(HCE_exists);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public void addNewStudy(JFrameBase frame) { // Adds a new Study manually.
        System.out.println("<<<<<<<<<< START OF addNewStudy >>>>>>>>>>");
        StudyPanelView studyPanelView = new StudyPanelView(frame);  // Creates a studyPanelView instance inside JFrameBase.
        try{     
            // Collection of Ids involved in the creation of new study 
            Integer Patient_Id = frame.selectedPatientId;   // Assigns the new Study to the selected last patient. 
            DB2Hash patient = consultation.getAttributes("patient", Patient_Id);
            //System.out.println("Patient_Id: "+Patient_Id);1
            // Integer Device_Id = consultation.getFirstId("device");  // Get deviceId that will be used later.
            DB2Hash device = consultation.getAttributes("device");    // Get device data from database.            
            Integer Device_Id = Integer.parseInt(device.get("Id"));  // Get deviceId that will be used later.
            Integer Physician_Id = studyPanelView.getSelectedPhysicianId();
            
            String UIDprefix = device.get("DeviceUID");            
            ArrayList<String> studyKeys = consultation.getKeys("study");
            
            DB2Hash study = studyPanelView.getStudyData(studyKeys,UIDprefix);   // Get study data from view.            
            System.out.println("study: "+study);
            // Preparing consultation to overwrite it.
            ArrayList<String> consultationKeys = consultation.getKeys("consultation");
            DB2Hash consultationHash = new DB2Hash();                                           
            DB2Hash oldWorklist = null;                        
            DB2Hash oldStudy = null;
            
            if(!study.isEmpty()){
                boolean isNew = studyPanelView.isNew;   // If UID is empty, the study is new.
                System.out.println("isNew: "+isNew);
                if(isNew){  // Create a new study
                                        
                    // Study Hashtable
                    study.set("Id", null);        
                    Integer Study_Id = consultation.add(study,"study",true);    // New studyId after writting it in the database.
                    
                    if(Study_Id == null){
                        Study_Id = consultation.getId("study", "StudyId", study.get("StudyId"));
                        System.out.println("Updating study: "+Study_Id);
                        String error = "Este estudio ya había sido incluído en la base de datos.\n Revise posible dupliciadad en los datos del estudio.";
                        throw new MyException(MyException.DBUpdateError, error);
                    } 
                    
                    study.set("Id", Study_Id.toString());  // Add the new studyId after writting it in the database.
                    //System.out.println("Study_Id: "+Study_Id);
                                       
                                        
                    //Puntero en null para worklistId!!!
                    List<String> values = Arrays.asList(null,Study_Id.toString(),Physician_Id.toString(),Patient_Id.toString(),Device_Id.toString());   // Worklist Hashtable: Not obligatory, so if it doesn't exist set to null.
                    //consultationHash.set("worklist", null);
                    for(int i = 1; i<consultationKeys.size();i++){  // Doesn't write Id value.
                        System.out.println("Keys: "+consultationKeys.get(i)+" Values: "+values.get(i));
                        consultationHash.put(consultationKeys.get(i), values.get(i));
                    }
                    // Writting new tables on database.                    
                    consultation.add(consultationHash, "consultation",false);
                                        
                }else{  // Update an old study.
                    Integer studyId = consultation.getId("study","StudyInstanceUID",study.get("StudyInstanceUID")); // Get Study Id from UID data to add it to the rest of study data taken from view.                    
                    oldWorklist = this.consultation.getAttributes("worklist", "study", studyId);    // Get the worklist linked to this study from DB. There is a worklist for this study?
                    oldStudy = consultation.getAttributes("study", studyId);  // Get study saved in the database.
                    study.set("Id", studyId.toString());    // Set studyId from DB.
                    consultation.update(study,"study");     // Update data in DB.
                }
                JOptionPane.showMessageDialog(frame.ClinicPanel, studyAdded, frame.infoTxt,JOptionPane.INFORMATION_MESSAGE);
                for (int i = 0; i < controllerAddListener.size(); i++) {
                    controllerAddListener.get(i).updateEditStudy(isNew,patient,oldStudy,oldWorklist,study);
                }
            }
            
        }catch(MyException ex){//JOptionPane.ERROR_MESSAGE
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ClinicPanel, error_txt, ex.getTitle(), ex.getType(), null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }catch(SQLException ex){//JOptionPane.ERROR_MESSAGE
            //studyPanelView.clearAll();  // If there is an error saving the study, datafields will be cleared.            
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ClinicPanel, error_txt, frame.MYSQL_EXCEPTION, 2, null);
        }catch(Exception ex){   // GetAttributes throws this exception.
            String error_txt = Application.splitError(ex.toString());
            //JOptionPane.showMessageDialog(frame.ClinicPanel, error_txt, frame.EXCEPTION, 2, null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, error_txt);
        }
        System.out.println("<<<<<<<<<< END OF addNewStudy >>>>>>>>>>");
    }
    public void addNewAcquisition(JFrameBase frame) { // Adds a new Study manually.
        System.out.println("<<<<<<<<<< START OF addNewAcquisition >>>>>>>>>>");
        AcquisitionPanelView acquisitionPanelView = new AcquisitionPanelView(frame);  // Creates a studyPanelView instance inside JFrameBase.
        try{
            // Collection of Ids involved in the creation of new acquisition UNUSED
            Integer Patient_Id = frame.selectedPatientId;   // Assigns the new Study to the selected last patient.
            DB2Hash patient = consultation.getAttributes("patient", Patient_Id);
            //System.out.println("Patient_Id: "+Patient_Id);
            Integer Study_Id = frame.selectedStudyId;
            DB2Hash study = consultation.getAttributes("study", Study_Id);  // Get study from its Id.
            DB2Hash physician = this.consultation.getAttributes("physician", "study", Study_Id);    // Get physician from study Id.
            DB2Hash worklist = this.consultation.getAttributes("worklist", "study", Study_Id);  // Get worklist from study Id.
            System.out.println("Study_Id: "+Study_Id);
            
            ArrayList<String> acquisitionKeys = consultation.getKeys("acquisition");
            DB2Hash acquisition = acquisitionPanelView.getAcquisitionData(acquisitionKeys, Study_Id);   // Get acquisition data from view.
            System.out.println("acquisition: "+acquisition);
                        
            DB2Hash oldAcquisition = null;
            if(!acquisition.isEmpty()){   // We have catched some data from getAcquisitionData.
                boolean isNew = acquisitionPanelView.isNew;   // If AcquisitionName is empty, the acquisition is new.
                System.out.println("isNew: "+isNew);
                if(isNew){  // Create a new acquisition

                    // Study Hashtable
                    acquisition.set("Id", null);
                    Integer Acquisition_Id = consultation.add(acquisition,"acquisition",true);    // New acquisitionId after writting it in the database.
                    
                    if(Acquisition_Id == null){
                        Acquisition_Id = consultation.getId("acquisition", "AcquisitionName", acquisition.get("AcquisitionName"));
                        System.out.println("Updating acquisition: "+Acquisition_Id);
                        String error = "Esta adquisición ya había sido incluída en la base de datos.\n Revise posible dupliciadad en el identificador de adquisición 'AcquisitionName'\no en la imágen cargada 'ImagePath'.";
                        throw new MyException(MyException.DBUpdateError, error);
                    }
                    
                    acquisition.set("Id", Acquisition_Id.toString());  // Add the new studyId after writting it in the database.
                    //System.out.println("Acquisition_Id: "+Acquisition_Id);

                    DB2Hash device = consultation.getAttributes("device");    // Get device data from database.

                    jpg2dcm = new JPG2dcm(physician, patient, study, acquisition, device, worklist);  // Creates a new DICOM file to send to the PACS.
                }else{  // Update an old study.
                    Integer Acquisition_Id = consultation.getId("acquisition","AcquisitionName",acquisition.get("AcquisitionName")); // Get Acquisition Id from fixed AcquisitionName taken from the view.
                    //Integer Acquisition_Id = consultation.getId("acquisition","Id",frame.selectedAcquisitionId); // In principle it's the same getting the Acquisition Id from selectedAcquisitionId in JFrameBase.
                    
                    oldAcquisition = consultation.getAttributes("acquisition", Acquisition_Id);  // Get study saved in the database.
                    acquisition.set("Id", Acquisition_Id.toString());    // Set studyId from DB.
                    consultation.update(acquisition,"acquisition");     // Update data in DB.
                    
                    if(!oldAcquisition.get("ImagePath").equals(acquisition.get("ImagePath"))){  // If the image asociated to the acquisition has changed, delete the old one from database. If it's an error it rest undeleted.
                        System.out.println("The image asociated to the acquisition has changed: \noldAcquisition: "+oldAcquisition.get("ImagePath")+" --> acquisition:"+acquisition.get("ImagePath"));
                        FLib.deleteFile(oldAcquisition.get("ImagePath"));
                    }
                    
                }
                JOptionPane.showMessageDialog(frame.ImagePanel, acquisitionAdded, frame.infoTxt,JOptionPane.INFORMATION_MESSAGE);

                for (int i = 0; i < controllerAddListener.size(); i++) {
                    controllerAddListener.get(i).updateEditAcquisition(isNew,study,oldAcquisition,acquisition);
                }
            }
        }catch(MyException ex){//JOptionPane.ERROR_MESSAGE
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ImagePanel, error_txt, ex.getTitle(), ex.getType(), null);
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }catch(SQLException ex){//JOptionPane.ERROR_MESSAGE
            //acquisitionPanelView.clearAll();  // If there is an error saving the study, datafields will be cleared.
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ImagePanel, error_txt, frame.MYSQL_EXCEPTION, 2, null);
        }catch (FileLibrary.MyException ex) {   // Errors related to dcm file deletion.
            String error = ex.getMessage();
            JOptionPane.showMessageDialog(frame, error);
        }catch(Exception ex){      // GetAttributes throws this exception.
            String error_txt = Application.splitError(ex.toString());
            JOptionPane.showMessageDialog(frame.ImagePanel, error_txt, frame.EXCEPTION, 2, null);
        }
        System.out.println("<<<<<<<<<< END OF addNewAcquisition >>>>>>>>>>");
    }
    /*public void checkStudyUID(String UID) {   // Checks Patient UID when is writed in it's textfield.
        int UID_exists = 1; // studyId == null.
        Integer studyId = consultation.checkUID(UID);
        System.out.println("studyId: "+studyId);
        if(UID.equals("")){
            UID_exists = 2;
        }else if(studyId != null){
            changeSelectedPatient(studyId);   // Load patient if exists a coincidence.            
            UID_exists = 0;
        }
        for (int i = 0; i < controllerAddListener.size(); i++) {
            controllerAddListener.get(i).checkAddUID(UID_exists);
        }
    }*/

    public void changeSelectedPatient(Integer patientId) {
        try {
            DB2Hash patient = this.consultation.getAttributes("patient", patientId);
            for (int i = 0; i < controllerListener.size(); i++) {
                controllerListener.get(i).updateSelectedPatient(patient);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void changeSelectedStudy(Integer studyId) throws SQLException, Exception {        
        DB2Hash study = this.consultation.getAttributes("study", studyId);
        DB2Hash physician = this.consultation.getAttributes("physician", "study", studyId);
        for (int i = 0; i < controllerListener.size(); i++) {
            controllerListener.get(i).updateSelectedStudy(study, physician);
        }
    }
    
    public void changeSelectedAcquisition(Integer acquisitionId) {
        try {
            DB2Hash acquisition = this.consultation.getAttributes("acquisition", acquisitionId);
            for (int i = 0; i < controllerListener.size(); i++) {
                controllerListener.get(i).updateSelectedAcquisition(acquisition);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void removeSelectedNode(Integer nodeId, int nodeLevel) throws SQLException{
        String tableName = null;
        switch(nodeLevel){
            case (1):   tableName = "patient";
                        /*for (int i = 0; i < controllerAddListener.size(); i++) {
                            controllerAddListener.get(i).updateDeletePatient();
                        }*/
                        break;
            case (2):   tableName = "study";
                        /*for (int i = 0; i < controllerAddListener.size(); i++) {
                            controllerAddListener.get(i).updateDeleteStudy();
                        }*/
                        break;
            case (3):   tableName = "acquisition";
                        /*for (int i = 0; i < controllerAddListener.size(); i++) {
                            controllerAddListener.get(i).updateDeleteAcquisition();
                        }*/
                        break;                                         
        }
        for (int i = 0; i < controllerAddListener.size(); i++) {
            controllerAddListener.get(i).updateDeleteNode();
        }
        consultation.delete(nodeId, tableName);       

    }
    
    public void loadPhysicianList() {
        try {
            removeAllPhysician(); // Erase all physicians from list.
            ArrayList<Integer> physiciansIdList = this.consultation.getList("physician", ORDER_BY_PHYSICIAN);
            System.out.println("physiciansList: " + physiciansIdList);
            for (int k = 0; k < physiciansIdList.size(); k++) {
                DB2Hash physician = this.consultation.getAttributes("physician", physiciansIdList.get(k)); // We get all data from physician due to all of it is related to the identification.
                addPhysician(physician);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void loadServerList() {
        try {
            // Put server names on combobox.
            removeAllServer(); // Erase all servers from list.
            ArrayList<Integer> serverIdList = this.consultation.getList("server", ORDER_BY_AET);    // Gets all servers AET in it's corresponding combobox.
            System.out.println("serverIdList: " + serverIdList);
            for (int k = 0; k < serverIdList.size(); k++) {
                DB2Hash server = this.consultation.getAttributes("server", serverIdList.get(k)); // We get all data from physician due to all of it is related to the identification.
                addServer(server);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
    
    public void treeSearch(String pattern) {
        for (int i = 0; i < controllerListener.size(); i++) {
            controllerListener.get(i).updateTreeSelection(pattern);
        }
    }
    
    public void loadPatientList(List<String> patientVar, String patientFilter) {
        try {
            System.out.println("<<<<<<<<<< START OF loadPatientList >>>>>>>>>>");
            this.consultation = new Consultation();
            
            ArrayList<Integer> patientsIdList = null;
            if(patientVar != null ){
                patientsIdList = this.consultation.getList("patient",patientVar,patientFilter,ORDER_BY_NAME);
            }else{
                patientsIdList = this.consultation.getList("patient",ORDER_BY_NAME);
            }

            ArrayList<Integer> studyIdList = null;
            //ArrayList<Integer> worklistIdList = null;
            //System.out.println("PatientsList: "+patientsIdList);
            for (int i = 0; i < patientsIdList.size(); i++) {
                ArrayList<Integer> acquisitionIdList = null;
                DB2Hash currentPatient = this.consultation.getAttributes("patient", patientsIdList.get(i));
                addPatient(currentPatient);                
                studyIdList = this.consultation.getList("study", "patient", patientsIdList.get(i), ORDER_BY_NAME_AND_STUDY);
                
                //worklistIdList = this.consultation.getWorklistList(patientsIdList.get(i),ORDER_BY_NAME_AND_WORKLIST);
                //System.out.println("studyIdList: " + studyIdList + " worklistIdList: " + worklistIdList); // Revised studies doesn't compt.
                System.out.println("studyIdList: " + studyIdList); // Revised studies doesn't compt.
                for (int j = 0; j < studyIdList.size(); j++) {
                    DB2Hash studyNames = this.consultation.getAttributes("study", studyIdList.get(j));
                    DB2Hash worklistNames = this.consultation.getAttributes("worklist", "study", studyIdList.get(j));
                    //DB2Hash physicianNames = this.consultation.getAttributes("physician", "worklist", "PhysicianId",worklistNames.get("Id"));   // Load physicians from worklist.
                    //System.out.println("WorklistNames: "+worklistNames);
                    addStudy(studyNames, worklistNames);    // Add study + worklist data.
                    //System.out.println("PatientId: "+patientsIdList.get(i)+" >>> StudyId: "+studyIdList.get(j));
                    acquisitionIdList = this.consultation.getAcquisitionList(studyIdList.get(j), ORDER_BY_STUDY);
                    //System.out.println("Current study id: "+studyIdList.get(j)+" AcquisitionIdList: "+acquisitionIdList);
                    for (int k = 0; k < acquisitionIdList.size(); k++) {
                        DB2Hash acquisitionNames = this.consultation.getAttributes("acquisition", acquisitionIdList.get(k));
                        //System.out.println("Current acquisition Times: "+acquisitionNames);
                        addAcquisition(acquisitionNames, Integer.parseInt(studyNames.get("Revised")));
                    }
                }
                removePatient(); // Removes empty patients from Worklist tree.
            }
            System.out.println("<<<<<<<<<< END OF loadPatientList >>>>>>>>>>");
        } catch (SQLException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public ArrayList<Server> getServerNames() throws SQLException, Exception{   // ArrayList of server DBHash.
        // Used in JFrameConfig.
        this.consultation = new Consultation();
        ArrayList<Server> serverNames = new ArrayList<Server>();
        
        ArrayList<Integer> serverIdList = this.consultation.getList("server", ORDER_BY_AET);
        //System.out.println("serverList: " + serverList);
        for (int i = 0; i < serverIdList.size(); i++) {
            DB2Hash server = this.consultation.getAttributes("server", serverIdList.get(i));
            Server currentServer = new Server(server);
            serverNames.add(currentServer);
        }
        return serverNames;
    }
    /*public Device getDevice() throws SQLException, Exception{   // ArrayList of server DBHash.
        // Used in JFrameConfig.
        this.consultation = new Consultation();        
        DB2Hash device = this.consultation.getAttributes("device"); // Get attributes from the first row.
        Device currentDevice = new Device(device);

        return currentDevice;
    }*/

    public void addPhysician(DB2Hash physician) {
        for (int i = 0; i < controllerAddListener.size(); i++) {
            controllerAddListener.get(i).updateAddPhysician(physician);
        }
    }
    public void addServer(DB2Hash server) {
        for (int i = 0; i < controllerAddListener.size(); i++) {
            controllerAddListener.get(i).updateAddServer(server);
        }
    }
    public void addReferralnote(ArrayList<DB2Hash> referralNote) {
        for (int i = 0; i < controllerAddListener.size(); i++) {
            controllerAddListener.get(i).updateAddReferralnote(referralNote);
        }
    }
    public void deleteReferralnotes() {
        for (int i = 0; i < controllerAddListener.size(); i++) {
            controllerAddListener.get(i).deleteReferralnotes();
        }
    }
    public void previewReferralnote(DB2Hash worklist2db,DB2Hash study2db,DB2Hash patient2db) {
        for (int i = 0; i < controllerAddListener.size(); i++) {
            controllerAddListener.get(i).previewReferralnote(worklist2db,study2db,patient2db);
        }
    }
    
    public void removeAllPhysician() {
        for (int i = 0; i < controllerUpdateListener.size(); i++) {
            controllerUpdateListener.get(i).deletePhysicianList();
        }
    }
    public void removeAllServer() {
        for (int i = 0; i < controllerUpdateListener.size(); i++) {
            controllerUpdateListener.get(i).deleteServerList();
        }
    }
    public void addPatient(DB2Hash patientNames) {
        for (int i = 0; i < controllerUpdateListener.size(); i++) {
            controllerUpdateListener.get(i).updatePatientList(patientNames);
        }        
    }
    public void addStudy(DB2Hash studyNames, DB2Hash worklistNames) {
        for (int i = 0; i < controllerUpdateListener.size(); i++) {
            controllerUpdateListener.get(i).updateStudyList(studyNames, worklistNames);
        }
    }
    public void addAcquisition(DB2Hash acquisitionNames, Integer revised) {
        for (int i = 0; i < controllerUpdateListener.size(); i++) {
            controllerUpdateListener.get(i).updateAcquisitionList(acquisitionNames, revised);
        }
    }
    public void removePatient() {
        for (int i = 0; i < controllerUpdateListener.size(); i++) {
            controllerUpdateListener.get(i).removeEmptyPatients();
        }
    }
        
    public interface ControllerUpdateListener {
        void deletePhysicianList();        
        void deleteServerList();
        void updatePatientList(DB2Hash patientNames);
        void updateStudyList(DB2Hash studyNames, DB2Hash worklistNames);
        //void updateAcquisitionList(DB2Hash acquisitionNames, Integer StudyId);
        void updateAcquisitionList(DB2Hash acquisitionNames, Integer Revised);
        void removeEmptyPatients();
        //void updateSelectedPhysician(int physicianId);
    }
    public interface ControllerListener {        
        //void updateSelectedPhysician(DB2Hash patient);
        void updateSelectedPatient(DB2Hash patient);
        void updateSelectedStudy(DB2Hash study, DB2Hash physician);
        void updateSelectedAcquisition(DB2Hash acquisition);

        void updateTreeSelection(String pattern);
    }
    public interface ControllerAddListener {
        void updateEditPatient(boolean isNew, DB2Hash oldPatient, DB2Hash patient);
        void updateEditStudy(boolean isNew, DB2Hash patient, DB2Hash oldStudy, DB2Hash oldWorklist, DB2Hash study);
        void updateEditAcquisition(boolean isNew, DB2Hash study, DB2Hash oldAcquisition, DB2Hash acquisition);
        void updateDeleteNode();
        //void updateAddStudy();
        //void updateDeleteStudy();
        void updateAddAcquisition();
        //void updateDeleteAcquisition();
        void updateAddPhysician(DB2Hash physician);
        void updateAddServer(DB2Hash server);
        void updateAddReferralnote(ArrayList<DB2Hash> referralNote);
        void deleteReferralnotes();
        void previewReferralnote(DB2Hash worklist2db,DB2Hash study2db,DB2Hash patient2db);

        void checkAddHCE(int HCE_exists);
    }
    public ArrayList<ControllerUpdateListener> controllerUpdateListener = new ArrayList();  
    public ArrayList<ControllerListener> controllerListener = new ArrayList();  
    public ArrayList<ControllerAddListener> controllerAddListener = new ArrayList();

    public void registerUpdateListener( ControllerUpdateListener controllerUpdateListener ) { this.controllerUpdateListener.add(controllerUpdateListener); }
    public void registerListener( ControllerListener controllerListener ) { this.controllerListener.add(controllerListener); }
    public void registerAddListener( ControllerAddListener controllerAddListener ) { this.controllerAddListener.add(controllerAddListener); }

}